home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Explore the World of Software 2
/
Explore the World of Software 2.iso
/
atm
/
winfont3
/
fontangl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-28
|
15KB
|
538 lines
#include "windows.h"
#include "fontangl.h"
/* Sample Angled Font Manipulation Module
*/
extern long FAR PASCAL lstrlen();
extern long FAR PASCAL lstrcpy();
extern long FAR PASCAL lstrcat();
int yCoord; /* the y coordinate of the starting text */
int nFirstIndex; /* the font currently displayed at the top */
int nLastIndex; /* the font currently displayed at the bottom */
int nTopClipped; /* the clipped portion of the top line of text */
int nBottomClipped; /* the clipped portion of the bottom line of text */
int nScrollBarTop; /* the nLastIndex at which the scrollbar is at the top */
int nFontCount; /* number of fonts enumerated */
HFONT hFontANSIFIXED;
HBRUSH hbrWhite;
HBRUSH hbrBlack;
HBRUSH hbrGray;
char szName[ LF_FACESIZE + 10 ];
/* Save away all enumerated LogFonts and TextMetrics */
LOGFONT LF[ MAXFONTS ];
TEXTMETRIC TM[ MAXFONTS ];
/* the two callback routines */
static FARPROC eafproc;
static FARPROC cbproc;
typedef struct {
HDC hDC;
FARPROC lpCallbackFunc;
} EAFDataType;
MyCopyStruct( dst, src, size )
PSTR dst;
LPSTR src;
int size;
{
while (size--)
*dst++ = *src++;
}
BOOL MyCompStruct( pS1, pS2, size )
BYTE *pS1;
BYTE *pS2;
int size;
{
while (size--)
if (*pS1++ != *pS2++)
return FALSE;
return TRUE;
}
EnumAllFonts( hWnd, lpCallbackFunc )
HWND hWnd;
FARPROC lpCallbackFunc;
{
HDC hDC;
EAFDataType EAFData;
nFontCount = 0;
hDC = GetDC( hWnd );
(EAFData.hDC) = hDC;
(EAFData.lpCallbackFunc) = lpCallbackFunc;
/* Enumerates one font from each facename */
EnumFonts( hDC, (LPSTR)NULL, eafproc, (LPSTR)&EAFData );
ReleaseDC( hWnd, hDC );
}
short int FAR PASCAL EAFCallback( lpLogFont, lpTextMetrics, FontType, lpEAFData )
LOGFONT FAR *lpLogFont;
TEXTMETRIC FAR *lpTextMetrics;
WORD FontType;
EAFDataType FAR *lpEAFData;
{
/* Enumerates all fonts with the same facename */
return( EnumFonts( lpEAFData->hDC,
(LPSTR)lpLogFont->lfFaceName,
lpEAFData->lpCallbackFunc,
(LPSTR)NULL ) );
}
short int FAR PASCAL cb( lpLogfont, lpTextMetrics, nFontType, lpData )
LPLOGFONT lpLogfont;
LPTEXTMETRIC lpTextMetrics;
WORD nFontType;
LONG lpData;
{
/* Skip over any raster fonts. We only want vector fonts. */
/* ################################################################### */
if ( nFontType & RASTER_FONTTYPE ) return TRUE;
MyCopyStruct( (PSTR)&LF[nFontCount], (LPSTR)lpLogfont, sizeof(LOGFONT) );
MyCopyStruct( (PSTR)&TM[nFontCount], (LPSTR)lpTextMetrics, sizeof(TEXTMETRIC) );
/* Stop callback when we can't hold anymore */
if (++nFontCount == MAXFONTS)
return FALSE;
else
return TRUE;
}
/* ######################################################################### */
DWORD PlaceFont( hDC, x, y, pLogfont )
HDC hDC;
short x, y;
LOGFONT *pLogfont;
{
HFONT hLocalFont;
DWORD Extent;
hLocalFont = CreateFontIndirect( (LPLOGFONT)pLogfont );
SelectObject( hDC, (HANDLE)hLocalFont );
TextOut( hDC,
x, y,
(LPSTR)szName,
lstrlen((LPSTR)szName) );
Extent = GetTextExtent(hDC,
(LPSTR)szName,
lstrlen((LPSTR)szName) );
/* Blow away the memory allocated for the font */
SelectObject( hDC, hFontANSIFIXED );
DeleteObject( hLocalFont );
return ( Extent );
}
#define OPB() \
TextOut( hDC, CurX, CurY, (LPSTR)Buffer, Chars ); \
CurY += TextMetric.tmHeight + TextMetric.tmExternalLeading;
ShowFont( hDC, i, y, WindowWidth )
HDC hDC;
int i; /* index into LF and TM */
int y;
int WindowWidth;
{
LOGFONT *pLogfont;
short CurX, CurY;
DWORD Extent;
short OldBkMode;
short Angle;
char Buffer[256];
short Chars;
TEXTMETRIC TextMetric;
OldBkMode = SetBkMode( hDC, TRANSPARENT );
pLogfont = &(LF[i]);
GetTextMetrics( hDC, &TextMetric );
CurX = TextMetric.tmAveCharWidth;
CurY = y;
Chars = sprintf(Buffer, "lfCharSet = %d",
pLogfont->lfCharSet ); OPB();
Chars = sprintf(Buffer, "lfOutPrecision = %d",
pLogfont->lfOutPrecision ); OPB();
Chars = sprintf(Buffer, "lfClipPrecision = %d",
pLogfont->lfClipPrecision); OPB();
CurX = ( TextMetric.tmAveCharWidth + WindowWidth ) / 2;
CurY = y;
Chars = sprintf(Buffer, "lfQuality = %d",
pLogfont->lfQuality ); OPB();
Chars = sprintf(Buffer, "lfPitchAndFamily&0x03 = %d",
pLogfont->lfPitchAndFamily&0x03 ); OPB();
Chars = sprintf(Buffer, "lfPitchAndFamily&0xF0 = %d",
pLogfont->lfPitchAndFamily&0xF0 ); OPB();
lstrcpy( (LPSTR)szName, (LPSTR)" " );
lstrcat( (LPSTR)szName, (LPSTR)pLogfont->lfFaceName );
CurX = TM[i].tmAveCharWidth;
CurY = y;
pLogfont->lfEscapement = 3600-900;
pLogfont->lfOrientation = 0;
Extent = PlaceFont( hDC, CurX, CurY, pLogfont );
CurX += ( LOWORD(Extent) + WindowWidth ) / 2;
CurY += (HIWORD(Extent) - CHARHEIGHT( i ));
for (Angle = 0; Angle <= 1800; Angle += 225) {
pLogfont->lfEscapement = pLogfont->lfOrientation = Angle;
PlaceFont( hDC, CurX, CurY, pLogfont );
}
pLogfont->lfEscapement = 0;
pLogfont->lfOrientation = 0;
SetBkMode( hDC, OldBkMode );
}
/* ######################################################################### */
LONG FontAnglPaint( hDC, nRepaintBegin, nRepaintEnd, WindowWidth )
HDC hDC;
int nRepaintBegin, nRepaintEnd;
int WindowWidth;
{
int i, y, h;
/* Convert the nRepaintBegin line to a font index */
i = nFirstIndex;
y = -nTopClipped;
h = 0;
do {
y += h;
h = STRINGHEIGHT(i);
i++;
} while ( (i < nFontCount) && ( (y + h) < nRepaintBegin ));
/* Backtrack since we passed it */
i--;
/* Repaint until we pass the nRepaintEnd line */
for (; (i < nFontCount) && (y < nRepaintEnd); i++) {
ShowFont( hDC, i, y, WindowWidth );
y += STRINGHEIGHT(i);
}
/* Return the last displayed font index and its clipped amount */
h = y - nRepaintEnd;
return( MAKELONG( i-1, (h<0 ? 0 : h) ) );
}
int FontAnglScroll( hWnd, cmd )
HWND hWnd;
int cmd;
{
int samount, sm, h;
switch( cmd )
{
case SB_LINEDOWN:
if ((nLastIndex < nFontCount-1) || nBottomClipped) {
/* Figure out how much to scroll up:
* Reveal the bottom row if some part of it was hidded,
* otherwise bring in the next row.
*/
if (nBottomClipped)
sm = nBottomClipped;
else {
nLastIndex++;
sm = STRINGHEIGHT(nLastIndex);
}
samount = sm;
nBottomClipped = 0;
/* Move up enough rows to reveal the scroll amount */
h = STRINGHEIGHT(nFirstIndex) - nTopClipped;
while ( (sm-=h) >= 0 ) {
nFirstIndex++;
h = STRINGHEIGHT(nFirstIndex);
}
/* Clip the top row with the remaining pixels */
if (sm)
nTopClipped = STRINGHEIGHT(nFirstIndex) + sm;
else
nTopClipped = 0;
/* Scroll up */
ScrollWindow( hWnd,
0,
-samount,
(LPRECT)NULL,
(LPRECT)NULL );
SetScrollPos( hWnd, SB_VERT, nLastIndex-nScrollBarTop, TRUE );
}
break;
case SB_LINEUP:
if (nFirstIndex || nTopClipped) {
/* Figure out how much to scroll down */
if (nTopClipped)
sm = nTopClipped;
else {
nFirstIndex--;
sm = STRINGHEIGHT(nFirstIndex);
}
samount = sm;
nTopClipped = 0;
/* Move down enough rows to make top row completely visible */
h = STRINGHEIGHT(nLastIndex) - nBottomClipped;
while ( (sm-=h) >= 0 ) {
nLastIndex--;
h = STRINGHEIGHT(nLastIndex);
}
/* Figure out clipped amount as result of scrolling */
if (sm)
nBottomClipped = STRINGHEIGHT(nLastIndex) + sm;
else
nBottomClipped = 0;
/* Scroll down */
ScrollWindow( hWnd,
0,
samount,
(LPRECT)NULL,
(LPRECT)NULL );
SetScrollPos( hWnd, SB_VERT, nLastIndex-nScrollBarTop, TRUE );
}
break;
}
}
int FontAnglSize( hWnd, width, length )
HWND hWnd;
int width, length;
{
static int oldlength = 0;
/* Redraw completely if vertical position changed: avoid the
* ----- -----
* case where tiling changes from |---| to | | | and the last
* ----- -----
* font is displayed at the bottom.
*/
if (length != oldlength) {
nFirstIndex = 0;
nTopClipped = 0;
oldlength = length;
}
}
int FontAnglCommand( hWnd, cmd )
HWND hWnd;
WORD cmd;
{
if (cmd == START_SESSION) {
EnumAllFonts( hWnd, cbproc );
nFirstIndex = 0;
nTopClipped = 0;
InvalidateRect( hWnd, (LPRECT)NULL, TRUE );
UpdateWindow( hWnd );
}
}
long FAR PASCAL FontAnglWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
PAINTSTRUCT ps;
RECT rcEntire;
int i;
LONG l;
switch (message)
{
case WM_DESTROY:
PostQuitMessage( 0 );
break;
case WM_COMMAND:
FontAnglCommand( hWnd, wParam );
break;
case WM_PAINT:
GetClientRect( hWnd, (LPRECT)&rcEntire );
BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
l = FontAnglPaint( ps.hdc,
ps.rcPaint.top,
ps.rcPaint.bottom,
rcEntire.right - rcEntire.left );
/* If the whole client rectangle is repainted, remember the index
* of the last font displayed, and if it was clipped at the bottom.
* This info helps in scrolling.
*/
if (nFontCount &&
MyCompStruct( (BYTE *)&(ps.rcPaint), (BYTE *)&rcEntire, sizeof(RECT)))
{
nLastIndex = LOWORD( l );
nBottomClipped = HIWORD( l );
/* Redefine scrollbar if redrew from the top */
if (nFirstIndex==0) {
nScrollBarTop = nLastIndex;
i = (nFontCount-1)-nScrollBarTop;
if (i<=0) {
if (nBottomClipped)
SetScrollRange( hWnd, SB_VERT, 0, 1, FALSE );
else
/* No need to scroll */
SetScrollRange( hWnd, SB_VERT, 0, 32767, FALSE );
}
else
SetScrollRange( hWnd, SB_VERT, 0, i, FALSE );
SetScrollPos( hWnd, SB_VERT, 0, TRUE );
}
}
EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
break;
case WM_SIZE:
FontAnglSize( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_VSCROLL:
FontAnglScroll( hWnd, wParam );
break;
default :
return (DefWindowProc( hWnd, message, wParam, lParam));
break;
}
return(0L);
}
FontAnglInit( hInstance )
HANDLE hInstance;
{
PWNDCLASS pFontAnglClass;
/* Set up some default brushes */
hbrWhite = GetStockObject( WHITE_BRUSH );
hbrBlack = GetStockObject( BLACK_BRUSH );
hbrGray = GetStockObject( GRAY_BRUSH );
hFontANSIFIXED = GetStockObject ( ANSI_FIXED_FONT );
/* Allocate class structure in local heap */
pFontAnglClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );
pFontAnglClass->hIcon = LoadIcon( hInstance,(LPSTR)"fontangl" );
pFontAnglClass->hCursor = LoadCursor( NULL, IDC_ARROW );
pFontAnglClass->lpszMenuName = (LPSTR)"fontAngl";
pFontAnglClass->lpszClassName = (LPSTR)"FontAngl";
pFontAnglClass->hbrBackground = (HBRUSH)hbrWhite;
pFontAnglClass->style = CS_HREDRAW | CS_VREDRAW;
pFontAnglClass->lpfnWndProc = FontAnglWndProc;
pFontAnglClass->hInstance = hInstance;
if (!RegisterClass( (LPWNDCLASS)pFontAnglClass ) )
return FALSE;
LocalFree( (HANDLE)pFontAnglClass );
return TRUE; /* Initialization succeeded */
}
int PASCAL WinMain( hInstance, hPrev, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrev;
LPSTR lpszCmdLine;
int cmdShow;
{
MSG msg;
HWND hWnd;
if (!hPrev) {
if ( !FontAnglInit(hInstance) )
return( FALSE );
}
else {
GetInstanceData( hPrev, (PSTR)&hFontANSIFIXED, sizeof( HFONT ) );
GetInstanceData( hPrev, (PSTR)&hbrWhite, sizeof( hbrWhite ) );
GetInstanceData( hPrev, (PSTR)&hbrBlack, sizeof( hbrBlack ) );
GetInstanceData( hPrev, (PSTR)&hbrGray, sizeof( hbrGray ) );
}
hWnd = (HWND)CreateWindow(
(LPSTR) "FontAngl",
(LPSTR) "Angled Fonts",
WS_TILEDWINDOW | WS_VSCROLL,
0, 0, 0, 100,
(HANDLE)NULL,
(HANDLE)NULL,
(HANDLE)hInstance,
(HANDLE)NULL
);
eafproc = MakeProcInstance( (FARPROC)EAFCallback, hInstance );
cbproc = MakeProcInstance( (FARPROC)cb, hInstance );
ShowWindow(hWnd, cmdShow);
UpdateWindow( hWnd );
while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
TranslateMessage((LPMSG)&msg);
DispatchMessage((LPMSG)&msg);
}
return msg.wParam;
}